#define DENSITYSCENE_API __declspec(dllexport)
#include "GraphicRenderInterface.h"
#define VLD_FORCE_ENABLE
#include "vld.h"

CDensityScene::CDensityScene()
{
	
}


CDensityScene::~CDensityScene()
{

}


Point2f *CDensityScene::GetPaoWuXian11()
{
	Point2f *p;
	p = (Point2f *)malloc(51 * sizeof(Point2f));
	assert(p);

	float n;
	int i ;
	for(i = 0, n = 0.0; i < 51; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = sqrt(0.2 * n);
	}

	return p;
}



Point2f *CDensityScene::GetPaoWuXian12()
{
	Point2f *p1;
	p1 = (Point2f *)malloc(51 * sizeof(Point2f));
	assert(p1);
	float n;
	int i;
	for(i = 0, n = 0.0; i < 51; i++, n += 0.1)
	{
		p1[i].x = n;
		p1[i].y = sqrt(0.3  * n);
	}
	return p1;
}


Point2f *CDensityScene::GetPaoWuXian13()
{
	Point2f *p;
	p = (Point2f *)malloc(51 * sizeof(Point2f));
	assert(p);
	float n;
	int i;
	for (i = 0, n = 0.0; i < 51; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = sqrt(0.8 * n);
	}
	return p;
}



Point2f *CDensityScene::GetZuoBiaoZhou1()
{
	Point2f *p;
	p = (Point2f *)malloc(61 * sizeof(Point2f));
	assert(p);
	int i;
	float n;
	for (i = 0, n = 0.0; i < 61; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = 0.0;
	}
	return p;
}



void CDensityScene::DrawHeavyGas()
{
	Point2f *p2;
	Point2f *p3;
	Point2f *p4;
	Point2f *p5;

	p2 = GetPaoWuXian11();
	p3 = GetPaoWuXian12();
	p4 = GetZuoBiaoZhou1();
	p5 = GetPaoWuXian13();

	assert(p2);
	assert(p3);
	assert(p4);
	assert(p5);

	glColor3f(1.0f, 0.0f, 0.0f);
	glBegin(GL_QUADS);
	for (int i = 0; i < 50; i++)
	{
		glVertex2f(p2[i].x, p2[i].y);
		glVertex2f(p2[i+1].x, p2[i].y);
		glVertex2f(p3[i+1].x, p3[i+1].y);
		glVertex2f(p3[i].x, p3[i].y);
	}
	glEnd();

	glColor3f(1.0f, 1.0f, 0.0f);
	glBegin(GL_QUADS);
	for(int i = 0; i < 50; i++)
	{
		glVertex2f(p3[i].x, p3[i].y);
		glVertex2f(p3[i+1].x, p3[i+1].y);
		glVertex2f(p5[i+1].x, p5[i+1].y);
		glVertex2f(p5[i].x, p5[i].y);
	}
	glEnd();

	glColor3f(0.0, 0.0, 1.0);
	glBegin(GL_QUADS);
	for (int i = 0; i < 50; i++)
	{
		glVertex2f(p2[i].x, p2[i].y);
		glVertex2f(p2[i+1].x, p2[i+1].y);
		glVertex2f(p4[i+1].x, p4[i+1].y);
		glVertex2f(p4[i].x, p4[i].y);
	}
	glEnd();

	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINES);
	glVertex2f(0.0, 0.0);
	glVertex2f(0.0, 4.0);
	glVertex2f(0.0, 0.0);
	glVertex2f(10.0, 0.0);
	glEnd();


	free(p2);
	free(p3);
	free(p4);
	free(p5);
}




Point2f *CDensityScene::GetPaoWuXian21()
{
	Point2f *p;
	p = (Point2f *)malloc(19 * sizeof(Point2f));
	assert(p);
	int i;
	float n;
	for (i = 0, n = 0.0; i <= 18; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = -1.0/2.0 *((n - 1.0) * (n - 1.0)) + 1.0/2.0;
	}
	return p;
}



Point2f *CDensityScene::GetPaoWuXian22()
{
	Point2f *p;
	p = (Point2f *)malloc(37 * sizeof(Point2f));
	assert(p);
	int i;
	float n;
	for (i = 0, n = 0.0; i <= 36; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = -(1.0/4.0) * ((n - 2.0) * (n - 2.0)) + 1.0;
	}

	return p;
}



Point2f *CDensityScene::GetPaoWuXian23()
{
	Point2f *p;
	p = (Point2f *)malloc(67 * sizeof(Point2f));
	assert(p);
	int i;
	float n;
	for (i = 0, n = 0.0; i < 67; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = -(2.0/16.0) * ((n - 4.0) * (n - 4.0)) + 2.0;
	}
	return p;
}



Point2f *CDensityScene::GetZuoBiaoZhou2()
{
	Point2f *p;
	p = (Point2f *)malloc(90 * sizeof(Point2f));
	assert(p);
	int i;
	float n;
	for (i = 0, n = 0.0; i < 90; i++, n += 0.1)
	{
		p[i].x = n;
		p[i].y = 0.0;
	}
	return p;
}



void CDensityScene::DrawNonHeavyGas()
{
	Point2f *p1;
	Point2f *p2;
	Point2f *p3;
	Point2f *p4;
	p1 = GetPaoWuXian21();
	p2 = GetPaoWuXian22();
	p3 = GetPaoWuXian23();
	p4 = GetZuoBiaoZhou2();

	assert(p1);
	assert(p2);
	assert(p3);
	assert(p4);

	glColor3f(0.0, 0.0, 1.0);
	glBegin(GL_QUADS);
	for (int i = 0; i < 18; i++)
	{
		glVertex2f(p1[i].x, p1[i].y);
		glVertex2f(p1[i+1].x, p1[i+1].y);
		glVertex2f(p4[i+1].x, p4[i+1].y);
		glVertex2f(p4[i].x, p4[i].y);
	}
	glEnd();

	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_QUADS);
	for (int i = 0; i < 18; i++)
	{
		glVertex2f(p2[i].x, p2[i].y);
		glVertex2f(p2[i+1].x, p2[i+1].y);
		glVertex2f(p1[i+1].x, p1[i+1].y);
		glVertex2f(p1[i].x, p1[i].y);
	}
	for (int i = 18; i < 36; i++)
	{
		glVertex2f(p2[i].x, p2[i].y);
		glVertex2f(p2[i+1].x, p2[i+1].y);
		glVertex2f(p4[i+1].x, p4[i+1].y);
		glVertex2f(p4[i].x, p4[i].y);
	}
	glEnd();


	glColor3f(1.0, 1.0, 0.0);
	glBegin(GL_QUADS);
	for (int i = 0; i < 36; i++)
	{
		glVertex2f(p3[i].x, p3[i].y);
		glVertex2f(p3[i+1].x, p3[i+1].y);
		glVertex2f(p2[i+1].x, p2[i+1].y);
		glVertex2f(p2[i].x, p2[i].y);
	}
	for (int i = 36; i < 66; i++ )
	{
		glVertex2f(p3[i].x, p3[i].y);
		glVertex2f(p3[i+1].x, p3[i+1].y);
		glVertex2f(p4[i+1].x, p4[i+1].y);
		glVertex2f(p4[i].x, p4[i].y);
	}
	glEnd();

	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINES);
	glVertex2f(0.0, 0.0);
	glVertex2f(0.0, 4.0);
	glVertex2f(0.0, 0.0);
	glVertex2f(8.0, 0.0);
	glEnd();

	free(p1);
	free(p2);
	free(p3);
	free(p4);
}




void CDensityScene::DrawStr(GLfloat x, GLfloat y, char* format, ...)
{
	va_list args;
	char buffer[255], *s;

	va_start(args, format);
	vsprintf(buffer, format, args);
	va_end(args);

	glRasterPos2f(x, y);
	for (s = buffer; *s; s++)
	{
		glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *s);
	}
}



void CDensityScene::HorizontalLine(float x, float y)
{
	ListName1 = glGenLists(1);
	glNewList(ListName1, GL_COMPILE);
	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINES);
	glVertex2f(x, y);
	glVertex2f(x, -y);
	glEnd();
	glTranslatef(0.25, 0.0, 0.0);
	glEndList();
}




void CDensityScene::VerticalLine(float x, float y)
{
	ListName2 = glGenLists(2);
	glNewList(ListName2, GL_COMPILE);
	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINES);
	glVertex2f(x, y);
	glVertex2f(-x, y);
	glEnd();
	glTranslatef(0.0, 0.5, 0.0);
	glEndList();
}




void CDensityScene::DrawHorizontalLine()
{
	for (int i = 0; i < 18; i++)
	{
		glCallList(ListName1);
	}
	DrawStr(-3.1, -0.4, "10000");
	DrawStr(-2.1, -0.4, "20000");
	DrawStr(-1.5, -0.4, "30000");
	DrawStr(-1.0, -0.4, "40000");
	DrawStr(-0.2, -0.4, "50000");
}



void CDensityScene::DrawVerticalLine()
{
	for (int i = 0; i < 5; i++)
	{
		glCallList(ListName2);
	}
	DrawStr(-0.5, -1.5, "5000");
	DrawStr(-0.5, -0.8, "10000");
	DrawStr(-0.5, 0.2, "20000");
}



void CDensityScene::RenderHeavyGasScene()
{
	glPushMatrix();
	glScalef(0.6, 0.6, 0);
	glTranslatef(1.2, 1.0, 0.0);
	DrawHeavyGas();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-0.27, 0.6, 0.0);
	HorizontalLine(1, 0.1);
	DrawHorizontalLine();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(0.7, 0.1, 0.0);
	VerticalLine(0.1, 0.5);
	DrawVerticalLine();
	glPopMatrix();
}


void CDensityScene::RenderNonHeavyGasScene()
{
	glPushMatrix();
	glScalef(0.6, 0.6, 0);
	glTranslatef(1.2, 1.0, 0.0);
	DrawNonHeavyGas();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-0.27, 0.6, 0.0);
	HorizontalLine(1, 0.1);
	DrawHorizontalLine();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(0.7, 0.1, 0.0);
	VerticalLine(0.1, 0.5);
	DrawVerticalLine();
	glPopMatrix();
}



void CDensityScene::InitOpenGL()
{
	glShadeModel(GL_SMOOTH);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
}